package com.jhanlos.flights;

import java.awt.Color;

import gov.nasa.worldwind.Configuration;
import gov.nasa.worldwind.Model;
import gov.nasa.worldwind.WorldWind;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.awt.AWTInputHandler;
import gov.nasa.worldwind.awt.WorldWindowGLCanvas;
import gov.nasa.worldwind.examples.sunlight.AtmosphereLayer;
import gov.nasa.worldwind.examples.sunlight.LensFlareLayer;
import gov.nasa.worldwind.examples.sunlight.RectangularNormalTessellator;
import gov.nasa.worldwind.examples.sunlight.SunPositionProvider;
import gov.nasa.worldwind.geom.LatLon;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.geom.Vec4;
import gov.nasa.worldwind.layers.CompassLayer;
import gov.nasa.worldwind.layers.Layer;
import gov.nasa.worldwind.layers.SkyGradientLayer;
import gov.nasa.worldwind.layers.StarsLayer;
import gov.nasa.worldwind.layers.TiledImageLayer;
import gov.nasa.worldwind.layers.WorldMapLayer;
import gov.nasa.worldwind.layers.Earth.CountryBoundariesLayer;
import gov.nasa.worldwind.layers.Earth.USGSUrbanAreaOrtho;
import gov.nasa.worldwind.layers.Mercator.examples.OSMCycleMapLayer;
import gov.nasa.worldwind.layers.Mercator.examples.OSMMapnikLayer;
import gov.nasa.worldwind.layers.Mercator.examples.OSMMapnikTransparentLayer;
import gov.nasa.worldwind.layers.Mercator.examples.VirtualEarthLayer;
import gov.nasa.worldwind.layers.Mercator.examples.YahooMapsLayer;
import gov.nasa.worldwind.layers.placename.PlaceNameLayer;

import javax.swing.JFrame;

import com.jhanlos.flights.astro.bodies.Sun;
import com.jhanlos.flights.objects.Flights;
import com.jhanlos.flights.objects.FlightsModelRenderable;
import com.jhanlos.flights.time.Time;
import com.jhanlos.flights.worldwind.layers.AirportRenderableLayer;
import com.jhanlos.flights.worldwind.sunshader.CustomSunPositionProvider;


/**
 * 
 * @author Marck
 *
 */
public class AppletFlights extends JFrame {

private static final long serialVersionUID = 232323L;
	
	private WorldWindowGLCanvas wwd;
	
	
	
	Time currentJulianDate = new Time();
	
	//Sun manger
	private RectangularNormalTessellator tessellator;
	private LensFlareLayer lensFlareLayer;
	private AtmosphereLayer atmosphereLayer;
	private SunPositionProvider spp;
	private boolean sunShadingOn = false; 
	Sun sun;
	    
	AirportRenderableLayer airportRenderableLayer;
	
	
	
	
	public AppletFlights() {
		 
		Configuration.setValue(AVKey.TESSELLATOR_CLASS_NAME, RectangularNormalTessellator.class.getName());

		wwd = new WorldWindowGLCanvas();
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		this.add(wwd, java.awt.BorderLayout.CENTER);
		Model m = (Model) WorldWind.createConfigurationComponent(AVKey.MODEL_CLASS_NAME);
		m.setShowWireframeExterior(false);
        m.setShowWireframeInterior(false);
        m.setShowTessellationBoundingVolumes(false);
        m.getLayers().add(new CountryBoundariesLayer());
        
     // MS  Virtual Earth imagery
        VirtualEarthLayer ve = new VirtualEarthLayer();
        ve.setEnabled(false);  // off by default
        m.getLayers().add(ve);
        // yahoo imagergy
        YahooMapsLayer ya = new YahooMapsLayer();
        ya.setEnabled(false);  // off by default
        m.getLayers().add(ya);
        // open maps
        OSMMapnikLayer ol = new OSMMapnikLayer();
        ol.setEnabled(false);  // off by default
        m.getLayers().add(ol);
        OSMCycleMapLayer  ol2 = new OSMCycleMapLayer();
        ol2.setEnabled(false);  // off by default
        m.getLayers().add(ol2);
        OSMMapnikTransparentLayer  ol3 = new OSMMapnikTransparentLayer();
        ol3.setEnabled(false);  // off by default
        m.getLayers().add(ol3);
      
                
        
        wwd.setModel(m);
        
        
        Flights flights = new Flights(wwd.getModel().getGlobe());
        
        FlightsModelRenderable flightsModelRenderable = new FlightsModelRenderable(flights, wwd.getModel().getGlobe());
               
        airportRenderableLayer = new AirportRenderableLayer();
        
        airportRenderableLayer.addRenderable(flightsModelRenderable);
        
        m.getLayers().add(airportRenderableLayer);
        
        
        
     // SUN SHADING -------------

        sun = new Sun(currentJulianDate.getMJD());
        // set the sun provider to the shader
        spp = new CustomSunPositionProvider(sun);
              
     // Replace sky gradient with this atmosphere layer when using sun shading
        this.atmosphereLayer = new AtmosphereLayer();
        
        this.lensFlareLayer = LensFlareLayer.getPresetInstance(LensFlareLayer.PRESET_BOLD);
        this.wwd.getModel().getLayers().add(this.lensFlareLayer);

        // Get tessellator
        this.tessellator = (RectangularNormalTessellator)wwd.getModel().getGlobe().getTessellator();
        
        // set default colors for shading
        //this.tessellator.setLightColor(Color.CYAN); //this.colorButton.getBackground());
        //this.tessellator.setAmbientColor(Color.BLACK); //this.ambientButton.getBackground());
        this.tessellator.setAmbientColor(new Color(0.50f, 0.50f, 0.50f));
        
        setSunShadingOn(true);
        
        setupView();
		 
		 
	 }
	
	private void setupView()
    {
		
        
        // Earth View mode
            //AutoClipBasicOrbitView bov = new AutoClipBasicOrbitView();
            //wwd.setView(bov);
            
            // remove the rest of the old input handler  (does this need a remove of hover listener? - maybe it is now completely removed?)
            wwd.getInputHandler().setEventSource(null);
            
            AWTInputHandler awth = new AWTInputHandler();
            awth.setEventSource(wwd);
            wwd.setInputHandler(awth);
            //awth.setSmoothViewChanges(smoothViewChanges); // FALSE MAKES THE VIEW FAST!! -- MIGHT WANT TO MAKE IT GUI Chooseable
                        
            // IF EARTH VIEW -- RESET CLIPPING PLANES BACK TO NORMAL SETTINGS!!!
            //wwd.getView().setNearClipDistance(this.nearClippingPlaneDistOrbit);
            //wwd.getView().setFarClipDistance(this.farClippingPlaneDistOrbit);
            
            // change class for inputHandler
            Configuration.setValue(AVKey.INPUT_HANDLER_CLASS_NAME, 
                        AWTInputHandler.class.getName());

            
            //this.wwd.addSelectListener(new ViewControlsSelectListener(wwd, viewControlsLayer));
            
        
    }
	
	
	public void setSunShadingOn(boolean useSunShading)
    {
        if(useSunShading == sunShadingOn)
        {
            return; // nothing to do
        }

        sunShadingOn = useSunShading;

        if(sunShadingOn)
        {
            // enable shading - use special atmosphere
            for(int i = 0; i < this.wwd.getModel().getLayers().size(); i++)
            {
                Layer l = this.wwd.getModel().getLayers().get(i);
                if(l instanceof SkyGradientLayer)
                {
                    this.wwd.getModel().getLayers().set(i, this.atmosphereLayer);
                }
            }
        }
        else
        {
            // disable shading
            // Turn off lighting
            this.tessellator.setLightDirection(null);
            this.lensFlareLayer.setSunDirection(null);
            this.atmosphereLayer.setSunDirection(null);

            // use standard atmosphere
            for(int i = 0; i < this.wwd.getModel().getLayers().size(); i++)
            {
                Layer l = this.wwd.getModel().getLayers().get(i);
                if(l instanceof AtmosphereLayer)
                {
                    this.wwd.getModel().getLayers().set(i, new SkyGradientLayer());
                }
            }
            
        } // if/else shading

        this.update(true); // redraw
    }
	
	private void update(boolean redraw)
    {
        if(sunShadingOn) 
        {
            // Compute Sun position according to current date and time
            LatLon sunPos = spp.getPosition();
            Vec4 sun = wwd.getModel().getGlobe().computePointFromPosition(new Position(sunPos, 0)).normalize3();

            Vec4 light = sun.getNegative3();
            this.tessellator.setLightDirection(light);
            this.lensFlareLayer.setSunDirection(sun);
            this.atmosphereLayer.setSunDirection(sun);

            // Redraw if needed
            if(redraw)
            {
                this.wwd.redraw();
            }
        } 
        
    }
	
	public static void main(String[] args)
    {
		AppletFlights twwd = new AppletFlights();
		twwd.setSize(700, 700);
		twwd.setVisible(true);
		
    }
	
	
}
